home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 24 / CU Amiga Magazine's Super CD-ROM 24 (1998)(EMAP Images)(GB)(Track 1 of 2)[!][issue 1998-07].iso / CUCD / Utilities / vim-5.1 / src / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-06  |  40.3 KB  |  1,526 lines

  1. /* vi:set ts=8 sts=4 sw=4:
  2.  *
  3.  * VIM - Vi IMproved    by Bram Moolenaar
  4.  *
  5.  * Do ":help uganda"  in Vim to read copying and usage conditions.
  6.  * Do ":help credits" in Vim to see a list of people who contributed.
  7.  */
  8.  
  9. #define EXTERN
  10. #include "vim.h"
  11.  
  12. #ifdef SPAWNO
  13. # include <spawno.h>        /* special MSDOS swapping library */
  14. #endif
  15.  
  16. static void mainerr __ARGS((int, char_u *));
  17. static void usage __ARGS((void));
  18. static int get_number_arg __ARGS((char_u *p, int *idx, int def));
  19.  
  20. /*
  21.  * Type of error message.  These must match with errors[] in mainerr().
  22.  */
  23. #define ME_UNKNOWN_OPTION    0
  24. #define ME_TOO_MANY_ARGS    1
  25. #define ME_ARG_MISSING        2
  26. #define ME_GARBAGE        3
  27. #define ME_EXTRA_CMD        4
  28.  
  29.     static void
  30. mainerr(n, str)
  31.     int        n;
  32.     char_u  *str;
  33. {
  34.     static char    *(errors[]) =
  35.     {
  36.     "Unknown option",
  37.     "Too many edit arguments",
  38.     "Argument missing after",
  39.     "Garbage after option",
  40.     "Too many \"+command\" or \"-c command\" arguments",
  41.     };
  42.  
  43. #if defined(UNIX) || defined(__EMX__)
  44.     reset_signals();        /* kill us with CTRL-C here, if you like */
  45. #endif
  46.  
  47.     mch_errmsg(longVersion);
  48.     mch_errmsg("\n");
  49.     mch_errmsg(errors[n]);
  50.     if (str != NULL)
  51.     {
  52.     mch_errmsg(": \"");
  53.     mch_errmsg((char *)str);
  54.     mch_errmsg("\"");
  55.     }
  56.     mch_errmsg("\nMore info with: \"vim -h\"\n");
  57.  
  58.     mch_windexit(1);
  59. }
  60.  
  61.     static void
  62. usage()
  63. {
  64.     int            i;
  65.     static char_u *(use[]) =
  66.     {
  67.     (char_u *)"[file ..]       edit specified file(s)",
  68.     (char_u *)"-               read from stdin",
  69.     (char_u *)"-t tag          edit file where tag is defined",
  70. #ifdef QUICKFIX
  71.     (char_u *)"-q [errorfile]  edit file with first error"
  72. #endif
  73.     };
  74.  
  75. #if defined(UNIX) || defined(__EMX__)
  76.     reset_signals();        /* kill us with CTRL-C here, if you like */
  77. #endif
  78.  
  79.     mch_errmsg(longVersion);
  80.     mch_errmsg("\nusage:");
  81.     for (i = 0; ; ++i)
  82.     {
  83.     mch_errmsg(" vim [options] ");
  84.     mch_errmsg((char *)use[i]);
  85.     if (i == (sizeof(use) / sizeof(char_u *)) - 1)
  86.         break;
  87.     mch_errmsg("\n   or:");
  88.     }
  89.  
  90.     mch_errmsg("\n\nOptions:\n");
  91.     mch_errmsg("   --\t\t\tEnd of options\n");
  92. #ifdef HAVE_OLE
  93.     mch_errmsg("   -register\t\tRegister this gvim for OLE\n");
  94.     mch_errmsg("   -unregister\t\tUnregister gvim for OLE\n");
  95. #endif
  96. #ifdef USE_GUI
  97.     mch_errmsg("   -g\t\t\tRun using GUI (like \"gvim\")\n");
  98.     mch_errmsg("   -f\t\t\tForeground: Don't fork when starting GUI\n");
  99. #endif
  100.     mch_errmsg("   -v\t\t\tVi mode (like \"vi\")\n");
  101.     mch_errmsg("   -e\t\t\tEx mode (like \"ex\")\n");
  102.     mch_errmsg("   -s\t\t\tSilent (batch) mode (only for \"ex\")\n");
  103.     mch_errmsg("   -R\t\t\tReadonly mode (like \"view\")\n");
  104.     mch_errmsg("   -Z\t\t\tRestricted mode (like \"rvim\")\n");
  105.     mch_errmsg("   -b\t\t\tBinary mode\n");
  106. #ifdef LISPINDENT
  107.     mch_errmsg("   -l\t\t\tLisp mode\n");
  108. #endif
  109.     mch_errmsg("   -C\t\t\tCompatible with Vi: 'compatible'\n");
  110.     mch_errmsg("   -N\t\t\tNot fully Vi compatible: 'nocompatible'\n");
  111.     mch_errmsg("   -V[N]\t\tVerbose level\n");
  112.     mch_errmsg("   -n\t\t\tNo swap file, use memory only\n");
  113.     mch_errmsg("   -r\t\t\tList swap files and exit\n");
  114.     mch_errmsg("   -r (with file name)\tRecover crashed session\n");
  115.     mch_errmsg("   -L\t\t\tSame as -r\n");
  116. #ifdef AMIGA
  117.     mch_errmsg("   -f\t\t\tDon't use newcli to open window\n");
  118.     mch_errmsg("   -d <device>\t\tUse <device> for I/O\n");
  119. #endif
  120. #ifdef RIGHTLEFT
  121.     mch_errmsg("   -H\t\t\tstart in Hebrew mode\n");
  122. #endif
  123. #ifdef FKMAP
  124.     mch_errmsg("   -F\t\t\tstart in Farsi mode\n");
  125. #endif
  126.     mch_errmsg("   -T <terminal>\tSet terminal type to <terminal>\n");
  127.     mch_errmsg("   -o[N]\t\tOpen N windows (default: one for each file)\n");
  128.     mch_errmsg("   +\t\t\tStart at end of file\n");
  129.     mch_errmsg("   +<lnum>\t\tStart at line <lnum>\n");
  130.     mch_errmsg("   -c <command>\t\tExecute <command> first\n");
  131.     mch_errmsg("   -s <scriptin>\tRead commands from script file <scriptin>\n");
  132.     mch_errmsg("   -w <scriptout>\tAppend commands to script file <scriptout>\n");
  133.     mch_errmsg("   -W <scriptout>\tWrite commands to script file <scriptout>\n");
  134.     mch_errmsg("   -u <vimrc>\t\tUse <vimrc> instead of any .vimrc\n");
  135. #ifdef USE_GUI
  136.     mch_errmsg("   -U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc\n");
  137. #endif
  138. #ifdef VIMINFO
  139.     mch_errmsg("   -i <viminfo>\t\tUse <viminfo> instead of .viminfo\n");
  140. #endif
  141.     mch_errmsg("   -h\t\t\tprint Help and exit (this message)\n");
  142.  
  143. #ifdef USE_GUI_X11
  144. # ifdef USE_GUI_MOTIF
  145.     mch_errmsg("\nOptions recognised by gvim (Motif version):\n");
  146. # else
  147. #  ifdef USE_GUI_ATHENA
  148.     mch_errmsg("\nOptions recognised by gvim (Athena version):\n");
  149. #  endif /* USE_GUI_ATHENA */
  150. # endif /* USE_GUI_MOTIF */
  151.     mch_errmsg("   -display <display>\tRun vim on <display>\n");
  152.     mch_errmsg("   -iconic\t\tStart vim iconified\n");
  153. # if 0
  154.     mch_errmsg("   -name <name>\t\tUse resource as if vim was <name>\n");
  155.     mch_errmsg("\t\t\t  (Unimplemented)\n");
  156. # endif
  157.     mch_errmsg("   -background <color>\tUse <color> for the background (also: -bg)\n");
  158.     mch_errmsg("   -foreground <color>\tUse <color> for normal text (also: -fg)\n");
  159.     mch_errmsg("   -font <font>\t\tUse <font> for normal text (also: -fn)\n");
  160.     mch_errmsg("   -boldfont <font>\tUse <font> for bold text\n");
  161.     mch_errmsg("   -italicfont <font>\tUse <font> for italic text\n");
  162.     mch_errmsg("   -geometry <geom>\tUse <geom> for initial geometry (also: -geom)\n");
  163.     mch_errmsg("   -borderwidth <width>\tUse a border width of <width> (also: -bw)\n");
  164.     mch_errmsg("   -scrollbarwidth <width>\tUse a scrollbar width of <width> (also: -sw)\n");
  165.     mch_errmsg("   -menuheight <height>\tUse a menu bar height of <height> (also: -mh)\n");
  166.     mch_errmsg("   -reverse\t\tUse reverse video (also: -rv)\n");
  167.     mch_errmsg("   +reverse\t\tDon't use reverse video (also: +rv)\n");
  168.     mch_errmsg("   -xrm <resource>\tSet the specified resource\n");
  169. #endif /* USE_GUI_X11 */
  170.  
  171.     mch_windexit(1);
  172. }
  173.  
  174. #ifdef HAVE_LOCALE_H
  175. # include <locale.h>
  176. #endif
  177.  
  178. /* Maximum number of commands from + or -c options */
  179. #define MAX_ARG_CMDS 10
  180.  
  181. #ifndef PROTO        /* don't want a prototype for main() */
  182.     int
  183. #ifdef VIMDLL
  184. _export
  185. #endif
  186. main(argc, argv)
  187.     int            argc;
  188.     char      **argv;
  189. {
  190.     char_u       *initstr;            /* init string from environment */
  191.     char_u       *term = NULL;        /* specified terminal name */
  192.     char_u       *fname = NULL;        /* file name from command line */
  193.     char_u       *tagname = NULL;        /* tag from -t option */
  194.     char_u       *use_vimrc = NULL;        /* vimrc from -u option */
  195. #ifdef QUICKFIX
  196.     char_u       *use_ef = NULL;        /* 'errorfile' from -q option */
  197. #endif
  198.     int            n_commands = 0;        /* no. of commands from + or -c */
  199.     char_u       *commands[MAX_ARG_CMDS]; /* commands from + or -c option */
  200.     int            no_swap_file = FALSE;   /* "-n" option used */
  201.     int            c;
  202.     int            i;
  203.     int            bin_mode = FALSE;        /* -b option used */
  204.     int            window_count = 1;        /* number of windows to use */
  205.     int            arg_idx = 0;        /* index for arg_files[] */
  206.     int            had_minmin = FALSE;        /* found "--" option */
  207.     int            argv_idx;            /* index in argv[n][] */
  208.     int            want_full_screen = TRUE;
  209.     int            want_argument;        /* option with argument */
  210. #define EDIT_NONE   0        /* no edit type yet */
  211. #define EDIT_FILE   1        /* file name argument[s] given, use arg_files[] */
  212. #define EDIT_STDIN  2        /* read file from stdin */
  213. #define EDIT_TAG    3        /* tag name argument given, use tagname */
  214. #define EDIT_QF        4        /* start in quickfix mode */
  215.     int            edit_type = EDIT_NONE;  /* type of editing to do */
  216.     int            stdout_isatty;        /* is stdout a terminal? */
  217.     int            input_isatty;        /* is active input a terminal? */
  218.     OPARG        oa;                /* operator arguments */
  219.     WIN            *wp;
  220.  
  221. #if defined(MSDOS) || defined(WIN32) || defined(OS2)
  222.     /*
  223.      * Default mappings for some often used keys.
  224.      * Use the Windows (CUA) keybindings.
  225.      */
  226.     static struct initmap
  227.     {
  228.     char_u        *arg;
  229.     int        mode;
  230.     } initmappings[] =
  231.     {
  232. # ifdef USE_GUI
  233.     {(char_u *)"<C-PageUp> H", NORMAL+VISUAL},
  234.     {(char_u *)"<C-PageUp> <C-O>H",INSERT},
  235.     {(char_u *)"<C-PageDown> L$", NORMAL+VISUAL},
  236.     {(char_u *)"<C-PageDown> <C-O>L<C-O>$", INSERT},
  237.  
  238.     /* paste, copy and cut */
  239.     {(char_u *)"<S-Insert> \"*P", NORMAL},
  240.     {(char_u *)"<S-Insert> \"\"d\"*P", VISUAL},
  241.     {(char_u *)"<S-Insert> <C-R>*", INSERT+CMDLINE},
  242.     {(char_u *)"<C-Insert> \"*y", VISUAL},
  243.     {(char_u *)"<S-Del> \"*d", VISUAL},
  244.     {(char_u *)"<C-Del> \"*d", VISUAL},
  245.     {(char_u *)"<C-X> \"\"d", VISUAL},
  246.     /* Missing: CTRL-C (can't be mapped) and CTRL-V (means something) */
  247. # else
  248.     {(char_u *)"\316\204 H", NORMAL+VISUAL},    /* CTRL-PageUp is "H" */
  249.     {(char_u *)"\316\204 \017H",INSERT},        /* CTRL-PageUp is "^OH"*/
  250.     {(char_u *)"\316v L$", NORMAL+VISUAL},        /* CTRL-PageDown is "L$" */
  251.     {(char_u *)"\316v \017L\017$", INSERT},        /* CTRL-PageDown ="^OL^O$"*/
  252.     {(char_u *)"\316w <C-Home>", NORMAL+VISUAL},
  253.     {(char_u *)"\316w <C-Home>", INSERT+CMDLINE},
  254.     {(char_u *)"\316u <C-End>", NORMAL+VISUAL},
  255.     {(char_u *)"\316u <C-End>", INSERT+CMDLINE},
  256.  
  257.     /* paste, copy and cut */
  258. #  ifdef USE_CLIPBOARD
  259.     {(char_u *)"\316\324 \"*P", NORMAL},        /* SHIFT-Insert is "*P */
  260.     {(char_u *)"\316\324 \"\"d\"*P", VISUAL},   /* SHIFT-Insert is ""d"*P */
  261.     {(char_u *)"\316\324 \017\"*P", INSERT},    /* SHIFT-Insert is ^O"*P */
  262.     {(char_u *)"\316\325 \"*y", VISUAL},        /* CTRL-Insert is "*y */
  263.     {(char_u *)"\316\327 \"*d", VISUAL},        /* SHIFT-Del is "*d */
  264.     {(char_u *)"\316\330 \"*d", VISUAL},        /* CTRL-Del is "*d */
  265.     {(char_u *)"\030 \"\"d", VISUAL},        /* CTRL-X is ""d */
  266. #  else
  267.     {(char_u *)"\316\324 P", NORMAL},        /* SHIFT-Insert is P */
  268.     {(char_u *)"\316\324 d\"0P", VISUAL},        /* SHIFT-Insert is d"0P */
  269.     {(char_u *)"\316\324 \017P", INSERT},        /* SHIFT-Insert is ^OP */
  270.     {(char_u *)"\316\325 y", VISUAL},        /* CTRL-Insert is y */
  271.     {(char_u *)"\316\327 d", VISUAL},        /* SHIFT-Del is d */
  272.     {(char_u *)"\316\330 d", VISUAL},        /* CTRL-Del is d */
  273. #  endif
  274. # endif
  275.     };
  276. #endif
  277.  
  278. #if defined(macintosh)
  279.     /*
  280.      * Default mappings for some often used keys.
  281.      * Use the Standard MacOS binding.
  282.      */
  283.     static struct initmap
  284.     {
  285.     char_u        *arg;
  286.     int        mode;
  287.     } initmappings[] =
  288.     {
  289.     /* paste, copy and cut */
  290.     {(char_u *)"<D-v> \"*P", NORMAL},
  291.     {(char_u *)"<D-v> \"\"d\"*P", VISUAL},
  292.     {(char_u *)"<D-v> <C-R>*", INSERT+CMDLINE},
  293.     {(char_u *)"<D-c> \"*y", VISUAL},
  294.     {(char_u *)"<D-x> \"*d", VISUAL},
  295.     {(char_u *)"<Backspace> \"\"d", VISUAL},
  296.     };
  297. #endif
  298.  
  299. #ifdef __EMX__
  300.     _wildcard(&argc, &argv);
  301. #endif
  302.  
  303. #ifdef HAVE_LOCALE_H
  304.     setlocale(LC_ALL, "");    /* for ctype() and the like */
  305. #endif
  306.  
  307. #if defined(USE_GUI_WIN32) && defined(HAVE_OLE)
  308.     /* Check for special OLE command line parameters */
  309.     if (argc == 2 && (argv[1][0] == '-' || argv[1][0] == '/'))
  310.     {
  311.     /* Register Vim as an OLE Automation server */
  312.     if (STRICMP(argv[1] + 1, "register") == 0)
  313.     {
  314.         RegisterMe();
  315.         mch_windexit(0);
  316.     }
  317.  
  318.     /* Unregister Vim as an OLE Automation server */
  319.     if (STRICMP(argv[1] + 1, "unregister") == 0)
  320.     {
  321.         UnregisterMe(TRUE);
  322.         mch_windexit(0);
  323.     }
  324.  
  325.     /* Ignore an -embedding argument. It is only relevant if the
  326.      * application wants to treat the case when it is started manually
  327.      * differently from the case where it is started via automation (and
  328.      * we don't).
  329.      */
  330.     if (STRICMP(argv[1] + 1, "embedding") == 0)
  331.         argc = 1;
  332.     }
  333.  
  334.     {
  335.     int    bDoRestart = FALSE;
  336.  
  337.     InitOLE(&bDoRestart);
  338.     /* automatically exit after registering */
  339.     if (bDoRestart)
  340.         mch_windexit(0);
  341.     }
  342. #endif
  343.  
  344. #ifdef USE_GUI
  345.     gui_prepare(&argc, argv);    /* Prepare for possibly starting GUI sometime */
  346. #endif
  347.  
  348. #ifdef USE_CLIPBOARD
  349.     clip_init(FALSE);        /* Initialise clipboard stuff */
  350. #endif
  351.  
  352.     /*
  353.      * Check if we have an interactive window.
  354.      * On the Amiga: If there is no window, we open one with a newcli command
  355.      * (needed for :! to * work). mch_check_win() will also handle the -d
  356.      * argument.
  357.      */
  358.     stdout_isatty = (mch_check_win(argc, argv) != FAIL);
  359.  
  360.     /*
  361.      * allocate the first window and buffer. Can't do anything without it
  362.      */
  363.     if ((curwin = win_alloc(NULL)) == NULL ||
  364.             (curbuf = buflist_new(NULL, NULL, 1L, FALSE)) == NULL)
  365.     mch_windexit(0);
  366.     curwin->w_buffer = curbuf;
  367.     curbuf->b_nwindows = 1;    /* there is one window */
  368.     win_init(curwin);        /* init current window */
  369.     init_yank();        /* init yank buffers */
  370.  
  371.     /*
  372.      * Allocate space for the generic buffers (needed for set_init_1()).
  373.      */
  374.     if ((IObuff = alloc(IOSIZE)) == NULL ||
  375.                 (NameBuff = alloc(MAXPATHL)) == NULL)
  376.     mch_windexit(0);
  377.  
  378.     /*
  379.      * Set the default values for the options.
  380.      * First find out the home directory, needed to expand "~" in options.
  381.      */
  382.     init_homedir();        /* find real value of $HOME */
  383.     set_init_1();
  384.  
  385.     /*
  386.      * If the executable name starts with "r" we disable shell commands.
  387.      * If the next character is "g" we run the GUI version.
  388.      * If the next characters are "view" we start in readonly mode.
  389.      * If the next characters are "ex" we start in ex mode.
  390.      */
  391.     initstr = gettail((char_u *)argv[0]);
  392.  
  393.     if (initstr[0] == 'r')
  394.     {
  395.     restricted = TRUE;
  396.     ++initstr;
  397.     }
  398.  
  399.     if (initstr[0] == 'g')
  400.     {
  401. #ifdef USE_GUI
  402.     gui.starting = TRUE;
  403.     ++initstr;
  404. #else
  405.     mch_errmsg((char *)e_nogvim);
  406.     mch_windexit(2);
  407. #endif
  408.     }
  409.  
  410.     if (STRNCMP(initstr, "view", 4) == 0)
  411.     {
  412.     readonlymode = TRUE;
  413.     curbuf->b_p_ro = TRUE;
  414.     p_uc = 10000;            /* don't update very often */
  415.     }
  416.  
  417.     if (STRNCMP(initstr, "ex", 2) == 0)
  418.     {
  419.     exmode_active = TRUE;
  420.     change_compatible(TRUE);    /* set 'compatible' */
  421.     }
  422.  
  423.     /*
  424.      * On some systems, when we compile with the GUI, we always use it.  On Mac
  425.      * there is no terminal version, and on Windows we can't figure out how to
  426.      * fork one off with :gui.
  427.      */
  428. #ifdef ALWAYS_USE_GUI
  429.     gui.starting = TRUE;
  430. #endif
  431.  
  432.     ++argv;
  433.     --argc;
  434.  
  435. #ifndef macintosh
  436.     /*
  437.      * Allocate arg_files[], big enough to hold all potential file name
  438.      * arguments.
  439.      */
  440.     arg_files = (char_u **)alloc((unsigned)(sizeof(char_u *) * (argc + 1)));
  441.     if (arg_files == NULL)
  442.     mch_windexit(2);
  443. #else
  444.     arg_files = NULL;
  445. #endif
  446.     arg_file_count = 0;
  447.  
  448.     /*
  449.      * Process the command line arguments.
  450.      */
  451.     argv_idx = 1;        /* active option letter is argv[0][argv_idx] */
  452.     while (argc > 0)
  453.     {
  454.     /*
  455.      * "+" or "+{number}" or "+/{pat}" or "+{command}" argument.
  456.      */
  457.     if (argv[0][0] == '+' && !had_minmin)
  458.     {
  459.         if (n_commands >= MAX_ARG_CMDS)
  460.         mainerr(ME_EXTRA_CMD, NULL);
  461.         argv_idx = -1;        /* skip to next argument */
  462.         if (argv[0][1] == NUL)
  463.         commands[n_commands++] = (char_u *)"$";
  464.         else
  465.         commands[n_commands++] = (char_u *)&(argv[0][1]);
  466.     }
  467.  
  468.     /*
  469.      * Option argument.
  470.      */
  471.     else if (argv[0][0] == '-' && !had_minmin)
  472.     {
  473.         want_argument = FALSE;
  474.         c = argv[0][argv_idx++];
  475.         switch (c)
  476.         {
  477.         case NUL:        /* "-"  read from stdin */
  478.         if (edit_type != EDIT_NONE)
  479.             mainerr(ME_TOO_MANY_ARGS, (char_u *)argv[0]);
  480.         edit_type = EDIT_STDIN;
  481.         read_cmd_fd = 2;    /* read from stderr instead of stdin */
  482.         argv_idx = -1;        /* skip to next argument */
  483.         break;
  484.  
  485.         case '-':        /* "--" don't take any more options */
  486.         had_minmin = TRUE;
  487.         argv_idx = -1;        /* skip to next argument */
  488.         break;
  489.  
  490.         case 'b':        /* "-b" binary mode */
  491.         bin_mode = TRUE;    /* postpone to after reading .exrc files */
  492.         break;
  493.  
  494.         case 'C':        /* "-C"  Compatible */
  495.         change_compatible(TRUE);
  496.         break;
  497.  
  498.         case 'e':        /* "-e" Ex mode */
  499.         exmode_active = TRUE;
  500.         break;
  501.  
  502.         case 'f':        /* "-f"  GUI: run in foreground.  Amiga: open
  503.                 window directly, not with newcli */
  504. #ifdef USE_GUI
  505.         gui.dofork = FALSE;    /* don't fork() when starting GUI */
  506. #endif
  507.         break;
  508.  
  509.         case 'g':        /* "-g" start GUI */
  510. #ifdef USE_GUI
  511.         gui.starting = TRUE;    /* start GUI a bit later */
  512. #else
  513.         mch_errmsg((char *)e_nogvim);
  514.         mch_windexit(2);
  515. #endif
  516.         break;
  517.  
  518.         case 'F':        /* "-F" start in Farsi mode: rl + fkmap set */
  519. #ifdef FKMAP
  520.         curwin->w_p_rl = p_fkmap = TRUE;
  521. #else
  522.         mch_errmsg((char *)e_nofarsi);
  523.         mch_windexit(2);
  524. #endif
  525.         break;
  526.  
  527.         case 'h':        /* "-h" give help message */
  528.         usage();
  529.         break;
  530.  
  531.         case 'H':        /* "-H" start in Hebrew mode: rl + hkmap set */
  532. #ifdef RIGHTLEFT
  533.         curwin->w_p_rl = p_hkmap = TRUE;
  534. #else
  535.         mch_errmsg((char *)e_nohebrew);
  536.         mch_windexit(2);
  537. #endif
  538.         break;
  539.  
  540.         case 'l':        /* "-l" lisp mode, 'lisp' and 'showmatch' on */
  541. #ifdef LISPINDENT
  542.         curbuf->b_p_lisp = TRUE;
  543.         p_sm = TRUE;
  544. #endif
  545.         break;
  546.  
  547.         case 'N':        /* "-N"  Nocompatible */
  548.         change_compatible(FALSE);
  549.         break;
  550.  
  551.         case 'n':        /* "-n" no swap file */
  552.         no_swap_file = TRUE;
  553.         break;
  554.  
  555.         case 'o':        /* "-o[N]" open N windows */
  556.         /* default is 0: open window for each file */
  557.         window_count = get_number_arg((char_u *)argv[0], &argv_idx, 0);
  558.         break;
  559.  
  560. #ifdef QUICKFIX
  561.         case 'q':        /* "-q" QuickFix mode */
  562.         if (edit_type != EDIT_NONE)
  563.             mainerr(ME_TOO_MANY_ARGS, (char_u *)argv[0]);
  564.         edit_type = EDIT_QF;
  565.         if (argv[0][argv_idx])            /* "-q{errorfile}" */
  566.         {
  567.             use_ef = (char_u *)argv[0] + argv_idx;
  568.             argv_idx = -1;
  569.         }
  570.         else if (argc > 1)            /* "-q {errorfile}" */
  571.             want_argument = TRUE;
  572.         break;
  573. #endif
  574.  
  575.         case 'R':        /* "-R" readonly mode */
  576.         readonlymode = TRUE;
  577.         curbuf->b_p_ro = TRUE;
  578.         p_uc = 10000;            /* don't update very often */
  579.         break;
  580.  
  581.         case 'r':        /* "-r" recovery mode */
  582.         case 'L':        /* "-L" recovery mode */
  583.         recoverymode = 1;
  584.         break;
  585.  
  586.         case 's':
  587.         if (exmode_active)    /* "-s" silent (batch) mode */
  588.             silent_mode = TRUE;
  589.         else        /* "-s {scriptin}" read from script file */
  590.             want_argument = TRUE;
  591.         break;
  592.  
  593.         case 't':        /* "-t {tag}" or "-t{tag}" jump to tag */
  594.         if (edit_type != EDIT_NONE)
  595.             mainerr(ME_TOO_MANY_ARGS, (char_u *)argv[0]);
  596.         edit_type = EDIT_TAG;
  597.         if (argv[0][argv_idx])        /* "-t{tag}" */
  598.         {
  599.             tagname = (char_u *)argv[0] + argv_idx;
  600.             argv_idx = -1;
  601.         }
  602.         else                /* "-t {tag}" */
  603.             want_argument = TRUE;
  604.         break;
  605.  
  606.         case 'V':        /* "-V{N}"    Verbose level */
  607.         /* default is 10: a little bit verbose */
  608.         p_verbose = get_number_arg((char_u *)argv[0], &argv_idx, 10);
  609.         break;
  610.  
  611.         case 'v':        /* "-v"  Vi-mode (as if called "vi") */
  612.         exmode_active = FALSE;
  613.         break;
  614.  
  615.         case 'w':        /* "-w{number}"    set window height */
  616.                 /* "-w {scriptout}"    write to script */
  617.         if (isdigit(argv[0][argv_idx]))
  618.         {
  619.             argv_idx = -1;
  620.             break;            /* not implemented, ignored */
  621.         }
  622.         want_argument = TRUE;
  623.         break;
  624.  
  625.         case 'x':        /* "-x"  use "crypt" for reading/writing files. */
  626.         /* TODO */
  627.         break;
  628.  
  629.         case 'Z':        /* "-Z"  restricted mode */
  630.         restricted = TRUE;
  631.         break;
  632.  
  633.         case 'c':        /* "-c {command}" execute command */
  634.         case 'd':        /* "-d {device}" device (for Amiga) */
  635.         case 'i':        /* "-i {viminfo}" use for viminfo */
  636.         case 'T':        /* "-T {terminal}" terminal name */
  637.         case 'u':        /* "-u {vimrc}" vim inits file */
  638.         case 'U':        /* "-U {gvimrc}" gvim inits file */
  639.         case 'W':        /* "-W {scriptout}" overwrite */
  640.         want_argument = TRUE;
  641.         break;
  642.  
  643.         default:
  644.         mainerr(ME_UNKNOWN_OPTION, (char_u *)argv[0]);
  645.         }
  646.  
  647.         /*
  648.          * Handle options with argument.
  649.          */
  650.         if (want_argument)
  651.         {
  652.         /*
  653.          * Check for garbage immediately after the option letter.
  654.          */
  655.         if (argv[0][argv_idx] != NUL)
  656.             mainerr(ME_GARBAGE, (char_u *)argv[0]);
  657.  
  658.         --argc;
  659.         if (argc < 1)
  660.             mainerr(ME_ARG_MISSING, (char_u *)argv[0]);
  661.         ++argv;
  662.         argv_idx = -1;
  663.  
  664.         switch (c)
  665.         {
  666.         case 'c':        /* "-c {command}" execute command */
  667.             if (n_commands >= MAX_ARG_CMDS)
  668.             mainerr(ME_EXTRA_CMD, NULL);
  669.             commands[n_commands++] = (char_u *)argv[0];
  670.             break;
  671.  
  672.         /*    case 'd':   This is handled in mch_check_win() */
  673.  
  674. #ifdef QUICKFIX
  675.         case 'q':        /* "-q {errorfile}" QuickFix mode */
  676.             use_ef = (char_u *)argv[0];
  677.             break;
  678. #endif
  679.  
  680.         case 'i':        /* "-i {viminfo}" use for viminfo */
  681.             use_viminfo = (char_u *)argv[0];
  682.             break;
  683.  
  684.         case 's':        /* "-s {scriptin}" read from script file */
  685.             if (scriptin[0] != NULL)
  686.             {
  687.             mch_errmsg("Attempt to open script file again: \"");
  688.             mch_errmsg(argv[-1]);
  689.             mch_errmsg(" ");
  690.             mch_errmsg(argv[0]);
  691.             mch_errmsg("\"\n");
  692.             mch_windexit(2);
  693.             }
  694.             if ((scriptin[0] = fopen(argv[0], READBIN)) == NULL)
  695.             {
  696.             mch_errmsg("Cannot open \"");
  697.             mch_errmsg(argv[0]);
  698.             mch_errmsg("\" for reading\n");
  699.             mch_windexit(2);
  700.             }
  701.             if (save_typebuf() == FAIL)
  702.             mch_windexit(2);    /* out of memory */
  703.             break;
  704.  
  705.         case 't':        /* "-t {tag}" */
  706.             tagname = (char_u *)argv[0];
  707.             break;
  708.  
  709.         case 'T':        /* "-T {terminal}" terminal name */
  710.             /*
  711.              * The -T term option is always available and when
  712.              * HAVE_TERMLIB is supported it overrides the environment
  713.              * variable TERM.
  714.              */
  715. #ifdef USE_GUI
  716.             if (term_is_gui((char_u *)argv[0]))
  717.             gui.starting = TRUE;    /* start GUI a bit later */
  718.             else
  719. #endif
  720.             term = (char_u *)argv[0];
  721.             break;
  722.  
  723.         case 'u':        /* "-u {vimrc}" vim inits file */
  724.             use_vimrc = (char_u *)argv[0];
  725.             break;
  726.  
  727.         case 'U':        /* "-U {gvimrc}" gvim inits file */
  728.             use_gvimrc = (char_u *)argv[0];
  729.             break;
  730.  
  731.         case 'w':        /* "-w {scriptout}" append to script file */
  732.         case 'W':        /* "-W {scriptout}" overwrite script file */
  733.             if (scriptout != NULL)
  734.             {
  735.             mch_errmsg("Attempt to open script file again: \"");
  736.             mch_errmsg(argv[-1]);
  737.             mch_errmsg(" ");
  738.             mch_errmsg(argv[0]);
  739.             mch_errmsg("\"\n");
  740.             mch_windexit(2);
  741.             }
  742.             if ((scriptout = fopen(argv[0],
  743.                     c == 'w' ? APPENDBIN : WRITEBIN)) == NULL)
  744.             {
  745.             mch_errmsg("cannot open \"");
  746.             mch_errmsg(argv[0]);
  747.             mch_errmsg("\" for output\n");
  748.             mch_windexit(2);
  749.             }
  750.             break;
  751.         }
  752.         }
  753.     }
  754.  
  755.     /*
  756.      * File name argument.
  757.      */
  758.     else
  759.     {
  760.         argv_idx = -1;        /* skip to next argument */
  761.         if (edit_type != EDIT_NONE && edit_type != EDIT_FILE)
  762.         mainerr(ME_TOO_MANY_ARGS, (char_u *)argv[0]);
  763.         edit_type = EDIT_FILE;
  764.         arg_files[arg_file_count] = vim_strsave((char_u *)argv[0]);
  765.         if (arg_files[arg_file_count] != NULL)
  766.         ++arg_file_count;
  767.     }
  768.  
  769.     /*
  770.      * If there are no more letters after the current "-", go to next
  771.      * argument.  argv_idx is set to -1 when the current argument is to be
  772.      * skipped.
  773.      */
  774.     if (argv_idx <= 0 || argv[0][argv_idx] == NUL)
  775.     {
  776.         --argc;
  777.         ++argv;
  778.         argv_idx = 1;
  779.     }
  780.     }
  781.  
  782.     /*
  783.      * May expand wildcards in file names.
  784.      */
  785.     if (arg_file_count > 0)
  786.     {
  787. #if (!defined(UNIX) && !defined(__EMX__)) || defined(ARCHIE)
  788.     char_u        **new_arg_files;
  789.     int        new_arg_file_count;
  790.  
  791.     if (expand_wildcards(arg_file_count, arg_files, &new_arg_file_count,
  792.                     &new_arg_files, EW_FILE|EW_NOTFOUND) == OK
  793.         && new_arg_file_count != 0)
  794.     {
  795.         FreeWild(arg_file_count, arg_files);
  796.         arg_file_count = new_arg_file_count;
  797.         arg_files = new_arg_files;
  798.     }
  799. #endif
  800.     fname = arg_files[0];
  801.     }
  802.     if (arg_file_count > 1)
  803.     printf("%d files to edit\n", arg_file_count);
  804.  
  805.     RedrawingDisabled = TRUE;
  806.  
  807.     /*
  808.      * When listing swap file names, don't do cursor positioning et. al.
  809.      */
  810.     if (recoverymode && fname == NULL)
  811.     want_full_screen = FALSE;
  812.  
  813.     /*
  814.      * When starting the GUI, don't need to check capabilities of terminal.
  815.      */
  816. #ifdef USE_GUI
  817.     if (gui.starting)
  818.     want_full_screen = FALSE;
  819. #endif
  820.  
  821.     /*
  822.      * mch_windinit() sets up the terminal (window) for use.  This must be
  823.      * done after resetting full_screen, otherwise it may move the cursor
  824.      * (MSDOS).
  825.      * Note that we may use mch_windexit() before mch_windinit()!
  826.      */
  827.     mch_windinit();
  828.  
  829.     /*
  830.      * Print a warning if stdout is not a terminal.
  831.      * When starting in Ex mode and commands come from a file, set Silent mode.
  832.      */
  833.     input_isatty = mch_input_isatty();
  834.     if (exmode_active)
  835.     {
  836.     if (!input_isatty)
  837.         silent_mode = TRUE;
  838.     }
  839.     else if (want_full_screen && (!stdout_isatty || !input_isatty))
  840.     {
  841.     if (!stdout_isatty)
  842.         mch_errmsg("Vim: Warning: Output is not to a terminal\n");
  843.     if (!input_isatty)
  844.         mch_errmsg("Vim: Warning: Input is not from a terminal\n");
  845.     ui_delay(2000L, TRUE);
  846.     }
  847.  
  848.     if (want_full_screen)
  849.     {
  850.     termcapinit(term);    /* set terminal name and get terminal
  851.                    capabilities (will set full_screen) */
  852.     screen_start();        /* don't know where cursor is now */
  853.     }
  854.     screenclear();        /* clear screen (just inits screen structures,
  855.                     because starting is TRUE) */
  856.  
  857.     /*
  858.      * Set the default values for the options that use Rows and Columns.
  859.      */
  860.     ui_get_winsize();        /* inits Rows and Columns */
  861.     set_init_2();
  862.  
  863.     firstwin->w_height = Rows - 1;
  864.     cmdline_row = Rows - 1;
  865.  
  866.     if (full_screen)
  867.     msg_start();        /* in case a mapping or error message is printed */
  868.     msg_scroll = TRUE;
  869.     no_wait_return = TRUE;
  870.  
  871. #if defined(MSDOS) || defined(WIN32) || defined(OS2) || defined(macintosh)
  872.     /*
  873.      * Default mappings for some often used keys.
  874.      * Need to put string in allocated memory, because do_map() will modify it.
  875.      */
  876.     {
  877.     char_u *cpo_save = p_cpo;
  878.  
  879.     p_cpo = (char_u *)"";    /* Allow <> notation */
  880.     for (i = 0; i < sizeof(initmappings) / sizeof(struct initmap); ++i)
  881.     {
  882.         initstr = vim_strsave(initmappings[i].arg);
  883.         if (initstr != NULL)
  884.         {
  885.         do_map(0, initstr, initmappings[i].mode, FALSE);
  886.         vim_free(initstr);
  887.         }
  888.     }
  889.     p_cpo = cpo_save;
  890.     }
  891. #endif
  892.  
  893.     init_highlight(TRUE);    /* set the default highlight groups */
  894. #ifdef USE_GUI
  895.     parse_guicursor();        /* set cursor shapes from 'guicursor' */
  896. #endif
  897.  
  898.     /*
  899.      * If -u option given, use only the initializations from that file and
  900.      * nothing else.
  901.      */
  902.     if (use_vimrc != NULL)
  903.     {
  904.     if (STRCMP(use_vimrc, "NONE") == 0)
  905.     {
  906.         if (use_gvimrc == NULL)        /* don't load gvimrc either */
  907.         use_gvimrc = use_vimrc;
  908.     }
  909.     else
  910.     {
  911.         if (do_source(use_vimrc, FALSE, FALSE) != OK)
  912.         EMSG2("Cannot read from \"%s\"", use_vimrc);
  913.     }
  914.     }
  915.     else if (!silent_mode)
  916.     {
  917.     /*
  918.      * Get system wide defaults, if the file name is defined.
  919.      */
  920. #ifdef SYS_VIMRC_FILE
  921.     (void)do_source((char_u *)SYS_VIMRC_FILE, TRUE, FALSE);
  922. #endif
  923.  
  924.     /*
  925.      * Try to read initialization commands from the following places:
  926.      * - environment variable VIMINIT
  927.      * - user vimrc file (s:.vimrc for Amiga, ~/.vimrc otherwise)
  928.      * - second user vimrc file ($VIM/.vimrc for Dos)
  929.      * - environment variable EXINIT
  930.      * - user exrc file (s:.exrc for Amiga, ~/.exrc otherwise)
  931.      * - second user exrc file ($VIM/.exrc for Dos)
  932.      * The first that exists is used, the rest is ignored.
  933.      */
  934.     if (process_env((char_u *)"VIMINIT") == OK)
  935.         vimrc_found();
  936.     else
  937.     {
  938.         if (do_source((char_u *)USR_VIMRC_FILE, TRUE, TRUE) == FAIL
  939. #ifdef USR_VIMRC_FILE2
  940.         && do_source((char_u *)USR_VIMRC_FILE2, TRUE, TRUE) == FAIL
  941. #endif
  942.         && process_env((char_u *)"EXINIT") == FAIL
  943.         && do_source((char_u *)USR_EXRC_FILE, FALSE, FALSE) == FAIL)
  944.         {
  945. #ifdef USR_EXRC_FILE2
  946.         (void)do_source((char_u *)USR_EXRC_FILE2, FALSE, FALSE);
  947. #endif
  948.         }
  949.     }
  950.  
  951.     /*
  952.      * Read initialization commands from ".vimrc" or ".exrc" in current
  953.      * directory.  This is only done if the 'exrc' option is set.
  954.      * Because of security reasons we disallow shell and write commands
  955.      * now, except for unix if the file is owned by the user or 'secure'
  956.      * option has been reset in environmet of global ".exrc" or ".vimrc".
  957.      * Only do this if VIMRC_FILE is not the same as USR_VIMRC_FILE or
  958.      * SYS_VIMRC_FILE.
  959.      */
  960.     if (p_exrc)
  961.     {
  962. #ifdef UNIX
  963.         {
  964.         struct stat s;
  965.  
  966.         /* if ".vimrc" file is not owned by user, set 'secure' mode */
  967.         if (stat(VIMRC_FILE, &s) || s.st_uid != getuid())
  968.             secure = p_secure;
  969.         }
  970. #else
  971.         secure = p_secure;
  972. #endif
  973.  
  974.         i = FAIL;
  975.         if (fullpathcmp((char_u *)USR_VIMRC_FILE,
  976.                       (char_u *)VIMRC_FILE, FALSE) != FPC_SAME
  977. #ifdef USR_VIMRC_FILE2
  978.             && fullpathcmp((char_u *)USR_VIMRC_FILE2,
  979.                       (char_u *)VIMRC_FILE, FALSE) != FPC_SAME
  980. #endif
  981. #ifdef SYS_VIMRC_FILE
  982.             && fullpathcmp((char_u *)SYS_VIMRC_FILE,
  983.                       (char_u *)VIMRC_FILE, FALSE) != FPC_SAME
  984. #endif
  985.                 )
  986.         i = do_source((char_u *)VIMRC_FILE, TRUE, TRUE);
  987.  
  988.         if (i == FAIL)
  989.         {
  990. #ifdef UNIX
  991.         struct stat s;
  992.  
  993.         /* if ".exrc" is not owned by user set 'secure' mode */
  994.         if (stat(EXRC_FILE, &s) || s.st_uid != getuid())
  995.             secure = p_secure;
  996.         else
  997.             secure = 0;
  998. #endif
  999.         if (       fullpathcmp((char_u *)USR_EXRC_FILE,
  1000.                       (char_u *)EXRC_FILE, FALSE) != FPC_SAME
  1001. #ifdef USR_EXRC_FILE2
  1002.             && fullpathcmp((char_u *)USR_EXRC_FILE2,
  1003.                       (char_u *)EXRC_FILE, FALSE) != FPC_SAME
  1004. #endif
  1005.                 )
  1006.             (void)do_source((char_u *)EXRC_FILE, FALSE, FALSE);
  1007.         }
  1008.     }
  1009.     if (secure == 2)
  1010.         need_wait_return = TRUE;
  1011.     secure = 0;
  1012.     }
  1013.  
  1014.     /*
  1015.      * Recovery mode without a file name: List swap files.
  1016.      * This uses the 'dir' option, therefore it must be after the
  1017.      * initializations.
  1018.      */
  1019.     if (recoverymode && fname == NULL)
  1020.     {
  1021.     recover_names(NULL, TRUE, 0);
  1022.     mch_windexit(0);
  1023.     }
  1024.  
  1025.     /*
  1026.      * Set a few option defaults after reading .vimrc files:
  1027.      * 'title' and 'icon', Unix: 'shellpipe' and 'shellredir'.
  1028.      */
  1029.     set_init_3();
  1030.  
  1031.     /*
  1032.      * "-n" argument: Disable swap file by setting 'updatecount' to 0.
  1033.      * Note that this overrides anything from a vimrc file.
  1034.      */
  1035.     if (no_swap_file)
  1036.     p_uc = 0;
  1037.  
  1038. #ifdef FKMAP
  1039.     if (curwin->w_p_rl && p_altkeymap)
  1040.     {
  1041.     p_hkmap = FALSE;    /* Reset the Hebrew keymap mode */
  1042.     p_fkmap = TRUE;        /* Set the Farsi keymap mode */
  1043.     }
  1044. #endif
  1045.  
  1046.     if (bin_mode)            /* "-b" argument used */
  1047.     {
  1048.     set_options_bin(curbuf->b_p_bin, 1);
  1049.     curbuf->b_p_bin = 1;        /* binary file I/O */
  1050.     }
  1051.  
  1052. #ifdef USE_GUI
  1053.     if (gui.starting)
  1054.     gui_start();        /* will set full_screen to TRUE */
  1055. #endif
  1056.  
  1057. #ifdef VIMINFO
  1058.     /*
  1059.      * Read in registers, history etc, but not marks, from the viminfo file
  1060.      */
  1061.     if (*p_viminfo != NUL)
  1062.     read_viminfo(NULL, TRUE, FALSE, FALSE);
  1063. #endif /* VIMINFO */
  1064.  
  1065. #ifdef SPAWNO        /* special MSDOS swapping library */
  1066.     init_SPAWNO("", SWAP_ANY);
  1067. #endif
  1068.  
  1069. #ifdef QUICKFIX
  1070.     /*
  1071.      * "-q errorfile": Load the error file now.
  1072.      * If the error file can't be read, exit before doing anything else.
  1073.      */
  1074.     if (edit_type == EDIT_QF)
  1075.     {
  1076.     if (use_ef != NULL)
  1077.         set_string_option_direct((char_u *)"ef", -1, use_ef, TRUE);
  1078.     if (qf_init(p_ef) < 0)
  1079.     {
  1080.         out_char('\n');
  1081.         mch_windexit(3);
  1082.     }
  1083.     }
  1084. #endif
  1085.  
  1086.     /*
  1087.      * Don't set the file name if there was a command in .vimrc that already
  1088.      * loaded the file
  1089.      */
  1090.     if (curbuf->b_ffname == NULL)
  1091.     {
  1092.     (void)setfname(fname, NULL, TRUE);  /* includes maketitle() */
  1093.     ++arg_idx;                /* used first argument name */
  1094.     }
  1095.  
  1096.     if (window_count == 0)
  1097.     window_count = arg_file_count;
  1098.     if (window_count > 1)
  1099.     {
  1100.     /* Don't change the windows if there was a command in .vimrc that
  1101.      * already split some windows */
  1102.     if (firstwin->w_next == NULL)
  1103.         window_count = make_windows(window_count);
  1104.     else
  1105.         window_count = win_count();
  1106.     }
  1107.     else
  1108.     window_count = 1;
  1109.  
  1110.     /*
  1111.      * Start putting things on the screen.
  1112.      * Scroll screen down before drawing over it
  1113.      * Clear screen now, so file message will not be cleared.
  1114.      */
  1115.     starting = FALSE;
  1116.     no_wait_return = FALSE;
  1117.     msg_scroll = FALSE;
  1118.  
  1119. #ifdef USE_GUI
  1120.     /*
  1121.      * This seems to be required to make callbacks to be called now, instead
  1122.      * of after things have been put on the screen, which then may be deleted
  1123.      * when getting a resize callback.
  1124.      */
  1125.     if (gui.in_use)
  1126.     gui_wait_for_chars(50L);
  1127. #endif
  1128.  
  1129.     /*
  1130.      * When done something that is not allowed or error message call
  1131.      * wait_return.  This must be done before starttermcap(), because it may
  1132.      * switch to another screen. It must be done after settmode(TMODE_RAW),
  1133.      * because we want to react on a single key stroke.
  1134.      * Call settmode and starttermcap here, so the T_KS and T_TI may be
  1135.      * defined by termcapinit and redifined in .exrc.
  1136.      */
  1137.     settmode(TMODE_RAW);
  1138.     if (need_wait_return || msg_didany)
  1139.     wait_return(TRUE);
  1140.  
  1141.     starttermcap();        /* start termcap if not done by wait_return() */
  1142. #ifdef USE_MOUSE
  1143.     setmouse();                /* may start using the mouse */
  1144. #endif
  1145.     if (scroll_region)
  1146.     scroll_region_reset();        /* In case Rows changed */
  1147.  
  1148.     scroll_start();
  1149.     /*
  1150.      * Don't clear the screen when starting in Ex mode, unless using the GUI.
  1151.      */
  1152.     if (exmode_active
  1153. #ifdef USE_GUI
  1154.             && !gui.in_use
  1155. #endif
  1156.                     )
  1157.     must_redraw = CLEAR;
  1158.     else
  1159.     screenclear();            /* clear screen */
  1160.  
  1161.     no_wait_return = TRUE;
  1162.  
  1163.     if (recoverymode)            /* do recover */
  1164.     {
  1165.     msg_scroll = TRUE;        /* scroll message up */
  1166.     ml_recover();
  1167.     msg_scroll = FALSE;
  1168.     if (curbuf->b_ml.ml_mfp == NULL) /* failed */
  1169.         getout(1);
  1170.     do_modelines();            /* do modelines */
  1171.     }
  1172.     else
  1173.     {
  1174.     /*
  1175.      * If "-" argument given: read file from stdin.
  1176.      * Need to stop Raw mode for terminal in case stdin and stderr are the
  1177.      * same terminal: "cat | vim -".
  1178.      */
  1179.     if (edit_type == EDIT_STDIN)
  1180.     {
  1181.         stoptermcap();
  1182.         settmode(TMODE_COOK);    /* set to normal mode */
  1183.         (void)open_buffer(TRUE);    /* create memfile and read file */
  1184.         if (!termcap_active)    /* if readfile() didn't do it already */
  1185.         {
  1186.         settmode(TMODE_RAW);    /* set to raw mode */
  1187.         starttermcap();
  1188.         }
  1189.     }
  1190.  
  1191.     /*
  1192.      * Open a buffer for windows that don't have one yet.
  1193.      * Commands in the .vimrc might have loaded a file or split the window.
  1194.      * Watch out for autocommands that delete a window.
  1195.      */
  1196. #ifdef AUTOCMD
  1197.     /*
  1198.      * Don't execute Win/Buf Enter/Leave autocommands here
  1199.      */
  1200.     ++autocmd_no_enter;
  1201.     ++autocmd_no_leave;
  1202. #endif
  1203.     for (curwin = firstwin; curwin != NULL; curwin = curwin->w_next)
  1204.     {
  1205.         curbuf = curwin->w_buffer;
  1206.         if (curbuf->b_ml.ml_mfp == NULL)
  1207.         {
  1208.         (void)open_buffer(FALSE);   /* create memfile and read file */
  1209. #ifdef AUTOCMD
  1210.         curwin = firstwin;        /* start again */
  1211. #endif
  1212.         }
  1213.         ui_breakcheck();
  1214.         if (got_int)
  1215.         {
  1216.         (void)vgetc();    /* only break the file loading, not the rest */
  1217.         break;
  1218.         }
  1219.     }
  1220. #ifdef AUTOCMD
  1221.     --autocmd_no_enter;
  1222.     --autocmd_no_leave;
  1223. #endif
  1224.     curwin = firstwin;
  1225.     curbuf = curwin->w_buffer;
  1226.     }
  1227.  
  1228.     /* Ex starts at last line of the file */
  1229.     if (exmode_active)
  1230.     curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
  1231.  
  1232. #ifdef AUTOCMD
  1233.     apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE);
  1234. #endif
  1235.     setpcmark();
  1236.  
  1237. #ifdef QUICKFIX
  1238.     /*
  1239.      * When started with "-q errorfile" jump to first error now.
  1240.      */
  1241.     if (edit_type == EDIT_QF)
  1242.     qf_jump(0, 0, FALSE);
  1243. #endif
  1244.  
  1245.     /*
  1246.      * If opened more than one window, start editing files in the other
  1247.      * windows.  Make_windows() has already opened the windows.
  1248.      */
  1249. #ifdef AUTOCMD
  1250.     /*
  1251.      * Don't execute Win/Buf Enter/Leave autocommands here
  1252.      */
  1253.     ++autocmd_no_enter;
  1254.     ++autocmd_no_leave;
  1255. #endif
  1256.     for (i = 1; i < window_count; ++i)
  1257.     {
  1258.     if (curwin->w_next == NULL)        /* just checking */
  1259.         break;
  1260.     win_enter(curwin->w_next, FALSE);
  1261.  
  1262.     /* Only open the file if there is no file in this window yet (that can
  1263.      * happen when .vimrc contains ":sall") */
  1264.     if (curbuf == firstwin->w_buffer || curbuf->b_ffname == NULL)
  1265.     {
  1266.         curwin->w_arg_idx = arg_idx;
  1267.         /* edit file from arg list, if there is one */
  1268.         (void)do_ecmd(0,
  1269.              arg_idx < arg_file_count ? arg_files[arg_idx] : NULL,
  1270.                       NULL, NULL, (linenr_t)0, ECMD_HIDE);
  1271.         if (arg_idx == arg_file_count - 1)
  1272.         arg_had_last = TRUE;
  1273.         ++arg_idx;
  1274.     }
  1275.     ui_breakcheck();
  1276.     if (got_int)
  1277.     {
  1278.         (void)vgetc();    /* only break the file loading, not the rest */
  1279.         break;
  1280.     }
  1281.     }
  1282. #ifdef AUTOCMD
  1283.     --autocmd_no_enter;
  1284. #endif
  1285.     win_enter(firstwin, FALSE);            /* back to first window */
  1286. #ifdef AUTOCMD
  1287.     --autocmd_no_leave;
  1288. #endif
  1289.     if (window_count > 1)
  1290.     win_equal(curwin, FALSE);        /* adjust heights */
  1291.  
  1292.     /*
  1293.      * If there are more file names in the argument list than windows,
  1294.      * put the rest of the names in the buffer list.
  1295.      */
  1296.     while (arg_idx < arg_file_count)
  1297.     (void)buflist_add(arg_files[arg_idx++]);
  1298.  
  1299.     /*
  1300.      * Need to jump to the tag before executing the '-c command'.
  1301.      * Makes "vim -c '/return' -t main" work.
  1302.      */
  1303.     if (tagname)
  1304.     {
  1305.     STRCPY(IObuff, "ta ");
  1306.     STRCAT(IObuff, tagname);
  1307.     do_cmdline(IObuff, NULL, NULL, DOCMD_NOWAIT|DOCMD_VERBOSE);
  1308.     }
  1309.  
  1310.     if (n_commands > 0)
  1311.     {
  1312.     /*
  1313.      * We start commands on line 0, make "vim +/pat file" match a
  1314.      * pattern on line 1.
  1315.      */
  1316.     curwin->w_cursor.lnum = 0;
  1317.     sourcing_name = (char_u *)"command line";
  1318.     for (i = 0; i < n_commands; ++i)
  1319.         do_cmdline(commands[i], NULL, NULL, DOCMD_NOWAIT|DOCMD_VERBOSE);
  1320.     sourcing_name = NULL;
  1321.     if (curwin->w_cursor.lnum == 0)
  1322.         curwin->w_cursor.lnum = 1;
  1323.  
  1324. #ifdef QUICKFIX
  1325.     /* When started with "-q errorfile" jump to first again. */
  1326.     if (edit_type == EDIT_QF)
  1327.         qf_jump(0, 0, FALSE);
  1328. #endif
  1329.     }
  1330.  
  1331.     RedrawingDisabled = FALSE;
  1332.     redraw_later(NOT_VALID);
  1333.     no_wait_return = FALSE;
  1334.  
  1335.     /* start in insert mode */
  1336.     if (p_im)
  1337.     need_start_insertmode = TRUE;
  1338.  
  1339. #ifdef AUTOCMD
  1340.     apply_autocmds(EVENT_VIMENTER, NULL, NULL, FALSE);
  1341. #endif
  1342.  
  1343.     /*
  1344.      * main command loop
  1345.      */
  1346.     clear_oparg(&oa);
  1347.     for (;;)
  1348.     {
  1349.     if (stuff_empty())
  1350.     {
  1351.         if (need_check_timestamps)
  1352.         check_timestamps();
  1353.         if (need_wait_return)    /* if wait_return still needed ... */
  1354.         wait_return(FALSE);    /* ... call it now */
  1355.         if (need_start_insertmode)
  1356.         {
  1357.         need_start_insertmode = FALSE;
  1358.         stuffReadbuff((char_u *)"i");    /* start insert mode next */
  1359.         /* skip the fileinfo message now, because it would be shown
  1360.          * after insert mode finishes! */
  1361.         need_fileinfo = FALSE;
  1362.         }
  1363.     }
  1364.     dont_wait_return = FALSE;
  1365.     if (got_int && !global_busy)
  1366.     {
  1367.         (void)vgetc();        /* flush all buffers */
  1368.         got_int = FALSE;
  1369.     }
  1370.     msg_scroll = FALSE;
  1371.     quit_more = FALSE;
  1372.  
  1373.     /*
  1374.      * If skip redraw is set (for ":" in wait_return()), don't redraw now.
  1375.      * If there is nothing in the stuff_buffer or do_redraw is TRUE,
  1376.      * update cursor and redraw.
  1377.      */
  1378.     if (skip_redraw || exmode_active)
  1379.         skip_redraw = FALSE;
  1380.     else if (do_redraw || stuff_empty())
  1381.     {
  1382.         /*
  1383.          * Before redrawing, make sure w_topline is correct, and w_leftcol
  1384.          * if lines don't wrap.
  1385.          */
  1386.         update_topline();
  1387.         if (!curwin->w_p_wrap)
  1388.         validate_cursor();
  1389.  
  1390.         if (VIsual_active)
  1391.         update_curbuf(INVERTED);/* update inverted part */
  1392.         else if (must_redraw)
  1393.         update_screen(must_redraw);
  1394.         else if (redraw_cmdline || clear_cmdline)
  1395.         showmode();
  1396.         for (wp = firstwin; wp; wp = wp->w_next)
  1397.         if (wp->w_redr_status)
  1398.             win_redr_status(wp);
  1399.         /* display message after redraw */
  1400.         if (keep_msg != NULL)
  1401.         msg_attr(keep_msg, keep_msg_attr);
  1402.         if (need_fileinfo)        /* show file info after redraw */
  1403.         {
  1404.         fileinfo(FALSE, TRUE, FALSE);
  1405.         need_fileinfo = FALSE;
  1406.         }
  1407.  
  1408.         emsg_on_display = FALSE;    /* can delete error message now */
  1409.         msg_didany = FALSE;        /* reset lines_left in msg_start() */
  1410.         do_redraw = FALSE;
  1411.         showruler(FALSE);
  1412.  
  1413.         setcursor();
  1414.         cursor_on();
  1415.     }
  1416.  
  1417.     /*
  1418.      * Update w_curswant if w_set_curswant has been set.
  1419.      * Postponed until here to avoid computing w_virtcol too often.
  1420.      */
  1421.     update_curswant();
  1422.  
  1423.     /*
  1424.      * If we're invoked as ex, do a round of ex commands.
  1425.      * Otherwise, get and execute a normal mode command.
  1426.      */
  1427.     if (exmode_active)
  1428.         do_exmode();
  1429.     else
  1430.         normal_cmd(&oa, TRUE);
  1431.     }
  1432.     /*NOTREACHED*/
  1433. #if !defined(MSDOS) || defined(DJGPP)
  1434.     return 0;    /* Borland C++ gives a "not reached" error message here */
  1435. #endif
  1436. }
  1437. #endif /* PROTO */
  1438.  
  1439. /*
  1440.  * Get a (optional) count for a Vim argument.
  1441.  */
  1442.     static int
  1443. get_number_arg(p, idx, def)
  1444.     char_u    *p;        /* pointer to argument */
  1445.     int        *idx;        /* index in argument, is incremented */
  1446.     int        def;        /* default value */
  1447. {
  1448.     if (isdigit(p[*idx]))
  1449.     {
  1450.     def = atoi((char *)&(p[*idx]));
  1451.     while (isdigit(p[*idx]))
  1452.         *idx = *idx + 1;
  1453.     }
  1454.     return def;
  1455. }
  1456.  
  1457. /*
  1458.  * Get an evironment variable, and execute it as Ex commands.
  1459.  * Returns FAIL if the environment variable was not executed, OK otherwise.
  1460.  */
  1461.     int
  1462. process_env(env)
  1463.     char_u    *env;
  1464. {
  1465.     char_u    *initstr;
  1466.  
  1467.     if ((initstr = vim_getenv(env)) != NULL && *initstr != NUL)
  1468.     {
  1469.     sourcing_name = env;
  1470.     do_cmdline(initstr, NULL, NULL, DOCMD_NOWAIT|DOCMD_VERBOSE);
  1471.     sourcing_name = NULL;
  1472.     return OK;
  1473.     }
  1474.     return FAIL;
  1475. }
  1476.  
  1477.     void
  1478. getout(r)
  1479.     int            r;
  1480. {
  1481.     exiting = TRUE;
  1482.  
  1483.     /* Position the cursor on the last screen line, below all the text */
  1484. #ifdef USE_GUI
  1485.     if (!gui.in_use)
  1486. #endif
  1487.     windgoto((int)Rows - 1, 0);
  1488.  
  1489. #ifdef HAVE_PERL_INTERP
  1490.     perl_end();
  1491. #endif
  1492.  
  1493. #ifdef VIMINFO
  1494.     if (*p_viminfo != NUL)
  1495.     {
  1496.     /* Write out the registers, history, marks etc, to the viminfo file */
  1497.     msg_didany = FALSE;
  1498.     write_viminfo(NULL, FALSE);
  1499.     if (msg_didany)        /* make the user read the error message */
  1500.     {
  1501.         no_wait_return = FALSE;
  1502.         wait_return(FALSE);
  1503.     }
  1504.     }
  1505. #endif /* VIMINFO */
  1506.  
  1507. #ifdef AUTOCMD
  1508.     apply_autocmds(EVENT_VIMLEAVE, NULL, NULL, FALSE);
  1509.  
  1510.     /* Position the cursor again, the autocommands may have moved it */
  1511. # ifdef USE_GUI
  1512.     if (!gui.in_use)
  1513. # endif
  1514.     windgoto((int)Rows - 1, 0);
  1515. #endif
  1516.  
  1517.     mch_windexit(r);
  1518. }
  1519.  
  1520. /*
  1521.  * When FKMAP is defined, also compile the Farsi source code.
  1522.  */
  1523. #ifdef FKMAP
  1524. # include "farsi.c"
  1525. #endif
  1526.